﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SPMS.Utility;
using SPMS.Log.Utility;

namespace SPMS.Log.ObjectFormatter
{
    /// <summary>
    /// 对象格式化器注册器
    /// </summary>
    /// <remarks>用于维护对象格式化器</remarks>
    /// <history>
    /// [zanezeng]               2010/1/13 14:12    创建
    /// </history>
    public sealed class ObjectFormatterRegistry : IObjectFormatterRegistry
    {
        #region ---IObjectFormatterRegistry

        /// <summary>
        /// 获得或者设置默认的对象格式化器
        /// </summary>
        /// <value>默认的对象格式化器</value>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]               2010/1/13 13:27    创建
        /// </history>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]               2010/1/13 14:13    创建
        /// </history>
        public IObjectFormatter DefaultFormatter
        {
            get
            {
                //判断是否设置了默认对象格式化器
                if (null == this.m_DefaultFormatter)
                {
                    //如果没有设置，则返回默认的对象格式化器的默认实例
                    return DefaultObjectFormatter.Default;
                }

                //返回设置的默认对象格式化器
                return this.m_DefaultFormatter;
            }
            set
            {
                this.m_DefaultFormatter = value;
            }
        }

        /// <summary>
        /// 清除所注册的对象格式化器
        /// </summary>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]               2010/1/13 13:27    创建
        /// </history>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]               2010/1/13 14:13    创建
        /// </history>
        public void Clear()
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// 注册给定对象类型的对象格式化器
        /// </summary>
        /// <param name="objectType">要注册的对象格式化器支持的对象类型</param>
        /// <param name="formatter">要注册的对象格式化器</param>
        /// <remarks></remarks>
        /// <exception cref="ArgumentNullException"><paramref name="objectType"/>或者<paramref name="formatter"/>为<c>null</c>引用。</exception>
        /// <history>
        /// [zanezeng]               2010/1/13 13:25    创建
        /// </history>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]               2010/1/13 14:14    创建
        /// </history>
        public void RegisterFormatter( Type objectType, IObjectFormatter formatter )
        {
            //断言参数
            ArgumentAssert.AssertArgumentNotNull( objectType, "objectType" );
            ArgumentAssert.AssertArgumentNotNull( formatter, "formatter" );

            //注册对象格式化器
            this.m_ObjectFormatters[objectType] = formatter;
        }

        /// <summary>
        /// 注销给定对象类型的对象格式化器
        /// </summary>
        /// <param name="objectType">要注销的对象格式化器支持的对象类型</param>
        /// <returns>被注销的对象格式化器。如果给定类型的对象格式化器不存在，则返回空引用。</returns>
        /// <remarks></remarks>
        /// <exception cref="ArgumentNullException"><paramref name="objectType"/>为<c>null</c>引用。</exception>
        /// <history>
        /// [zanezeng]               2010/1/13 14:07    创建
        /// </history>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]               2010/1/13 14:14    创建
        /// </history>
        public IObjectFormatter UnreigsterFormatter( Type objectType )
        {
            //断言参数
            ArgumentAssert.AssertArgumentNotNull( objectType, "objectType" );

            //用于保存返回的对象格式化器
            IObjectFormatter formatter = null;

            //尝试获得对象格式化器
            if (this.m_ObjectFormatters.TryGetValue( objectType, out formatter ))
            {
                //注销对象格式化器
                this.m_ObjectFormatters.Remove( objectType );
            }

            //返回获得的对象格式化器
            return formatter;
        }

        #endregion

        #region ---IObjectFormatterProvider

        /// <summary>
        /// 获得用于格式化给定类型对象的对象格式化器
        /// </summary>
        /// <param name="objectType">要被格式化的对象的对象类型</param>
        /// <returns>用于格式化给定类型对象的对象格式化器</returns>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]               2009/10/21 9:05    创建
        /// </history>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]               2010/1/13 14:15    创建
        /// </history>
        public IObjectFormatter GetFormatter( Type objectType )
        {
            //判断对象类型是否为空引用
            if (null == objectType)
            {
                //如果对象类型为空引用，则返回默认的对象格式化器
                return this.DefaultFormatter;
            }

            //用于保存对象格式化器
            IObjectFormatter formatter = null;

            //尝试获得给定类型的对象格式化器
            this.m_ObjectFormatters.TryGetValue( objectType, out formatter );

            //返回对象格式化器
            return (null == formatter) ? this.DefaultFormatter : formatter;
        }

        /// <summary>
        /// 获得用于格式化给定类型对象的对象格式化器
        /// </summary>
        /// <typeparam name="T">要被格式化的对象类型泛型参数</typeparam>
        /// <returns>用于格式化给定类型对象的对象格式化器</returns>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]               2010/1/13 14:09    创建
        /// </history>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]               2010/1/13 14:15    创建
        /// </history>
        public IObjectFormatter GetFormatter<T>()
        {
            return this.GetFormatter( typeof( T ) );
        }

        /// <summary>
        /// 获得用于格式化给定对象的对象格式化器
        /// </summary>
        /// <param name="obj">要被格式化的对象</param>
        /// <returns>用于格式化给定对象的对象格式化器</returns>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]               2010/1/13 14:10    创建
        /// </history>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]               2010/1/13 14:15    创建
        /// </history>
        public IObjectFormatter GetFormatter( object obj )
        {
            //判断对象是否为空引用
            if (null == obj)
            {
                //如果对象为空引用，则返回默认的对象格式化器
                return this.DefaultFormatter;
            }

            //返回对象格式化器
            return this.GetFormatter( obj.GetType() );
        }

        /// <summary>
        /// 将指定的对象格式化为字符串
        /// </summary>
        /// <param name="obj">要格式化的对象</param>
        /// <returns>给定对象的字符串描述信息</returns>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]               2009/9/29 11:49    创建
        /// </history>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]               2010/1/13 14:21    创建
        /// </history>
        public string FormatObject( object obj )
        {
            //格式化对象
            return this.FormatObjectCore( obj, null, null );
        }

        /// <summary>
        /// 将指定的对象格式化为字符串
        /// </summary>
        /// <param name="obj">要格式化的对象</param>
        /// <param name="format">对象的格式化字符串</param>
        /// <returns>给定对象的字符串描述信息</returns>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]               2009/10/20 10:57    创建
        /// </history>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]               2010/1/13 14:21    创建
        /// </history>
        public string FormatObject( object obj, string format )
        {
            //格式化对象
            return this.FormatObjectCore( obj, format, null );
        }

        /// <summary>
        /// 将指定的对象格式化为字符串
        /// </summary>
        /// <param name="obj">要格式化的对象</param>
        /// <param name="formatProvider">格式化提供者，提供用于检索控制格式化的对象的机制</param>
        /// <returns>给定对象的字符串描述信息</returns>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]               2009/10/20 10:57    创建
        /// </history>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]               2010/1/13 15:28    创建
        /// </history>
        public string FormatObject( object obj, IFormatProvider formatProvider )
        {
            //格式化对象
            return this.FormatObjectCore( obj, null, formatProvider );
        }

        /// <summary>
        /// 将指定的对象格式化为字符串
        /// </summary>
        /// <param name="obj">要格式化的对象</param>
        /// <param name="format">对象的格式化字符串</param>
        /// <param name="formatProvider">格式化提供者，提供用于检索控制格式化的对象的机制</param>
        /// <returns>给定对象的字符串描述信息</returns>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]               2009/10/20 10:57    创建
        /// </history>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]               2010/1/13 14:21    创建
        /// </history>
        public string FormatObject( object obj, string format, IFormatProvider formatProvider )
        {
            //格式化对象
            return this.FormatObjectCore( obj, format, formatProvider );
        }

        #endregion

        #region ---Private Method

        /// <summary>
        /// 将指定的对象格式化为字符串
        /// </summary>
        /// <param name="obj">要格式化的对象</param>
        /// <param name="format">对象的格式化字符串</param>
        /// <param name="formatProvider">格式化提供者，提供用于检索控制格式化的对象的机制</param>
        /// <returns>给定对象的字符串描述信息</returns>
        /// <remarks></remarks>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]               2010/1/13 14:32    创建
        /// </history>
        private string FormatObjectCore( object obj, string format, IFormatProvider formatProvider )
        {
            //格式化对象
            return this.GetFormatter( obj ).Format( this, obj, format, formatProvider );
        }

        #endregion

        #region ---Field

        /// <summary>
        /// 默认的对象格式化器
        /// </summary>
        private volatile IObjectFormatter m_DefaultFormatter;

        /// <summary>
        /// 对象格式化器字典
        /// </summary>
        private SynchronizedDictionary<Type, IObjectFormatter> m_ObjectFormatters = new SynchronizedDictionary<Type, IObjectFormatter>();

        #endregion
    }
}
